package main

import (
	"fmt"
)

// Product - 游戏角色
type GameCharacter struct {
	Name       string
	Class      string
	Level      int
	Attributes CharacterAttributes
	Skills     []Skill
	Equipment  Equipment
	Inventory  []Item
	Stats      CharacterStats
	Appearance CharacterAppearance
	Background CharacterBackground
}

type CharacterAttributes struct {
	Strength     int
	Dexterity    int
	Intelligence int
	Wisdom       int
	Constitution int
	Charisma     int
}

type Skill struct {
	Name        string
	Level       int
	Type        string
	Description string
}

type Equipment struct {
	Weapon      Item
	Armor       Item
	Shield      Item
	Accessories []Item
}

type Item struct {
	Name        string
	Type        string
	Rarity      string
	Stats       map[string]int
	Description string
}

type CharacterStats struct {
	Health       int
	Mana         int
	AttackPower  int
	Defense      int
	Speed        int
	CriticalRate float64
}

type CharacterAppearance struct {
	Gender    string
	HairColor string
	EyeColor  string
	Height    int
	Weight    int
	SkinTone  string
}

type CharacterBackground struct {
	Origin      string
	Profession  string
	Motivation  string
	Personality []string
}

func (gc *GameCharacter) Display() {
	fmt.Printf("角色信息:\n")
	fmt.Printf("  姓名: %s\n", gc.Name)
	fmt.Printf("  职业: %s\n", gc.Class)
	fmt.Printf("  等级: %d\n", gc.Level)
	fmt.Printf("  属性: 力量%d 敏捷%d 智力%d 智慧%d 体质%d 魅力%d\n",
		gc.Attributes.Strength, gc.Attributes.Dexterity, gc.Attributes.Intelligence,
		gc.Attributes.Wisdom, gc.Attributes.Constitution, gc.Attributes.Charisma)
	fmt.Printf("  生命值: %d, 法力值: %d\n", gc.Stats.Health, gc.Stats.Mana)
	fmt.Printf("  攻击力: %d, 防御力: %d, 速度: %d\n",
		gc.Stats.AttackPower, gc.Stats.Defense, gc.Stats.Speed)
	fmt.Printf("  技能数量: %d\n", len(gc.Skills))
	fmt.Printf("  背景: %s - %s\n", gc.Background.Origin, gc.Background.Profession)
}

// Abstract Builder - 抽象建造者
type CharacterBuilder interface {
	SetBasicInfo(name, class string, level int) CharacterBuilder
	SetAttributes(attributes CharacterAttributes) CharacterBuilder
	AddSkill(skill Skill) CharacterBuilder
	SetEquipment(equipment Equipment) CharacterBuilder
	AddInventoryItem(item Item) CharacterBuilder
	SetAppearance(appearance CharacterAppearance) CharacterBuilder
	SetBackground(background CharacterBackground) CharacterBuilder
	Build() *GameCharacter
}

// Concrete Builder - 具体建造者
type ConcreteCharacterBuilder struct {
	character *GameCharacter
}

func NewCharacterBuilder() *ConcreteCharacterBuilder {
	return &ConcreteCharacterBuilder{
		character: &GameCharacter{
			Skills:    make([]Skill, 0),
			Inventory: make([]Item, 0),
		},
	}
}

func (b *ConcreteCharacterBuilder) SetBasicInfo(name, class string, level int) CharacterBuilder {
	b.character.Name = name
	b.character.Class = class
	b.character.Level = level
	return b
}

func (b *ConcreteCharacterBuilder) SetAttributes(attributes CharacterAttributes) CharacterBuilder {
	b.character.Attributes = attributes
	return b
}

func (b *ConcreteCharacterBuilder) AddSkill(skill Skill) CharacterBuilder {
	b.character.Skills = append(b.character.Skills, skill)
	return b
}

func (b *ConcreteCharacterBuilder) SetEquipment(equipment Equipment) CharacterBuilder {
	b.character.Equipment = equipment
	return b
}

func (b *ConcreteCharacterBuilder) AddInventoryItem(item Item) CharacterBuilder {
	b.character.Inventory = append(b.character.Inventory, item)
	return b
}

func (b *ConcreteCharacterBuilder) SetAppearance(appearance CharacterAppearance) CharacterBuilder {
	b.character.Appearance = appearance
	return b
}

func (b *ConcreteCharacterBuilder) SetBackground(background CharacterBackground) CharacterBuilder {
	b.character.Background = background
	return b
}

func (b *ConcreteCharacterBuilder) Build() *GameCharacter {
	b.calculateStats()
	return b.character
}

func (b *ConcreteCharacterBuilder) calculateStats() {
	attr := b.character.Attributes

	b.character.Stats = CharacterStats{
		Health:       (attr.Constitution * 10) + (b.character.Level * 5),
		Mana:         (attr.Intelligence * 8) + (b.character.Level * 3),
		AttackPower:  attr.Strength + (b.character.Level * 2),
		Defense:      attr.Constitution + (b.character.Level * 1),
		Speed:        attr.Dexterity,
		CriticalRate: float64(attr.Dexterity) / 100.0,
	}

	if b.character.Equipment.Weapon.Name != "" {
		if attack, ok := b.character.Equipment.Weapon.Stats["attack"]; ok {
			b.character.Stats.AttackPower += attack
		}
	}

	if b.character.Equipment.Armor.Name != "" {
		if defense, ok := b.character.Equipment.Armor.Stats["defense"]; ok {
			b.character.Stats.Defense += defense
		}
	}
}

// Director - 指挥者
type CharacterDirector struct {
	builder CharacterBuilder
}

func NewCharacterDirector(builder CharacterBuilder) *CharacterDirector {
	return &CharacterDirector{builder: builder}
}

func (d *CharacterDirector) ConstructWarrior(name string) *GameCharacter {
	return d.builder.
		SetBasicInfo(name, "战士", 1).
		SetAttributes(CharacterAttributes{
			Strength:     18,
			Dexterity:    12,
			Intelligence: 8,
			Wisdom:       10,
			Constitution: 16,
			Charisma:     10,
		}).
		AddSkill(Skill{
			Name:        "重击",
			Level:       1,
			Type:        "攻击",
			Description: "造成额外伤害的强力攻击",
		}).
		AddSkill(Skill{
			Name:        "防御姿态",
			Level:       1,
			Type:        "防御",
			Description: "提高防御力，降低受到的伤害",
		}).
		SetEquipment(Equipment{
			Weapon: Item{
				Name:   "铁剑",
				Type:   "武器",
				Rarity: "普通",
				Stats:  map[string]int{"attack": 10},
			},
			Armor: Item{
				Name:   "皮甲",
				Type:   "护甲",
				Rarity: "普通",
				Stats:  map[string]int{"defense": 5},
			},
		}).
		AddInventoryItem(Item{
			Name:        "生命药水",
			Type:        "消耗品",
			Rarity:      "普通",
			Description: "恢复50点生命值",
		}).
		SetAppearance(CharacterAppearance{
			Gender:    "男",
			HairColor: "棕色",
			EyeColor:  "蓝色",
			Height:    180,
			Weight:    80,
			SkinTone:  "中等",
		}).
		SetBackground(CharacterBackground{
			Origin:      "北方王国",
			Profession:  "佣兵",
			Motivation:  "寻找失踪的家人",
			Personality: []string{"勇敢", "忠诚", "直率"},
		}).
		Build()
}

func (d *CharacterDirector) ConstructMage(name string) *GameCharacter {
	return d.builder.
		SetBasicInfo(name, "法师", 1).
		SetAttributes(CharacterAttributes{
			Strength:     8,
			Dexterity:    10,
			Intelligence: 18,
			Wisdom:       16,
			Constitution: 10,
			Charisma:     12,
		}).
		AddSkill(Skill{
			Name:        "火球术",
			Level:       1,
			Type:        "魔法",
			Description: "发射火球攻击敌人",
		}).
		AddSkill(Skill{
			Name:        "魔法护盾",
			Level:       1,
			Type:        "防御",
			Description: "创造魔法护盾抵挡攻击",
		}).
		SetEquipment(Equipment{
			Weapon: Item{
				Name:   "法师杖",
				Type:   "法杖",
				Rarity: "普通",
				Stats:  map[string]int{"magic_power": 8},
			},
			Armor: Item{
				Name:   "法师袍",
				Type:   "袍子",
				Rarity: "普通",
				Stats:  map[string]int{"mana": 20},
			},
		}).
		AddInventoryItem(Item{
			Name:        "法力药水",
			Type:        "消耗品",
			Rarity:      "普通",
			Description: "恢复30点法力值",
		}).
		SetAppearance(CharacterAppearance{
			Gender:    "女",
			HairColor: "银色",
			EyeColor:  "紫色",
			Height:    165,
			Weight:    55,
			SkinTone:  "白皙",
		}).
		SetBackground(CharacterBackground{
			Origin:      "魔法学院",
			Profession:  "学者",
			Motivation:  "探索古老的魔法知识",
			Personality: []string{"聪明", "好奇", "谨慎"},
		}).
		Build()
}

// 使用演示
func main() {
	fmt.Println("=== 角色建造者演示 ===")

	characterBuilder := NewCharacterBuilder()
	characterDirector := NewCharacterDirector(characterBuilder)

	// 创建战士
	warrior := characterDirector.ConstructWarrior("阿尔萨斯")
	fmt.Println("=== 战士角色 ===")
	warrior.Display()
	fmt.Println()

	// 创建法师
	characterBuilder = NewCharacterBuilder()
	characterDirector = NewCharacterDirector(characterBuilder)
	mage := characterDirector.ConstructMage("吉安娜")
	fmt.Println("=== 法师角色 ===")
	mage.Display()
}
